use crate::{AppError, AppResult, User};
use bcrypt::{hash, verify, DEFAULT_COST};
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Mutex;
use std::time::{SystemTime, UNIX_EPOCH};
use uuid::Uuid;

const JWT_SECRET: &str = "tauri_sip_secret_key_2024";
const TOKEN_EXPIRE_HOURS: u64 = 24;

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String, // 用户ID
    username: String,
    exp: u64,    // 过期时间
    iat: u64,    // 签发时间
    jti: String, // JWT ID
}

// 内存中的用户存储（实际项目中应该使用数据库）
lazy_static::lazy_static! {
    static ref USERS: Mutex<HashMap<String, User>> = Mutex::new(HashMap::new());
    static ref TOKENS: Mutex<HashMap<String, String>> = Mutex::new(HashMap::new());
}

pub struct AuthService;

impl AuthService {
    // 初始化默认用户
    pub fn init_default_users() {
        let mut users = USERS.lock().unwrap();
        
        // 创建默认管理员用户
        let admin_user = User {
            id: "admin".to_string(),
            username: "admin".to_string(),
            nickname: "系统管理员".to_string(),
            email: Some("admin@example.com".to_string()),
            phone: Some("13800138000".to_string()),
            avatar: None,
            status: crate::UserStatus::Active,
            role_ids: vec!["admin".to_string()],
            dept_id: Some("1".to_string()),
            dept_name: Some("技术部".to_string()),
            create_time: chrono::Utc::now(),
            update_time: chrono::Utc::now(),
            last_login_time: None,
        };
        
        users.insert("admin".to_string(), admin_user);
    }

    // 验证用户凭据
    pub fn verify_credentials(username: &str, password: &str) -> AppResult<User> {
        let users = USERS.lock().unwrap();
        
        if let Some(user) = users.get(username) {
            // 这里简化处理，实际项目中应该从数据库验证密码
            if username == "admin" && password == "admin123" {
                return Ok(user.clone());
            }
        }
        
        Err(AppError::AuthError("用户名或密码错误".to_string()))
    }

    // 生成JWT token
    pub fn generate_token(user: &User) -> AppResult<String> {
        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();
        
        let claims = Claims {
            sub: user.id.clone(),
            username: user.username.clone(),
            exp: now + (TOKEN_EXPIRE_HOURS * 3600),
            iat: now,
            jti: Uuid::new_v4().to_string(),
        };

        let token = encode(
            &Header::default(),
            &claims,
            &EncodingKey::from_secret(JWT_SECRET.as_ref()),
        )
        .map_err(|e| AppError::AuthError(format!("Token生成失败: {}", e)))?;

        // 存储token
        let mut tokens = TOKENS.lock().unwrap();
        tokens.insert(user.id.clone(), token.clone());

        Ok(token)
    }

    // 验证JWT token
    pub fn verify_token(token: &str) -> AppResult<User> {
        let token_data = decode::<Claims>(
            token,
            &DecodingKey::from_secret(JWT_SECRET.as_ref()),
            &Validation::default(),
        )
        .map_err(|e| AppError::AuthError(format!("Token验证失败: {}", e)))?;

        let claims = token_data.claims;
        
        // 检查token是否过期
        let now = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_secs();
        
        if claims.exp < now {
            return Err(AppError::AuthError("Token已过期".to_string()));
        }

        // 获取用户信息
        let users = USERS.lock().unwrap();
        users
            .get(&claims.sub)
            .cloned()
            .ok_or_else(|| AppError::AuthError("用户不存在".to_string()))
    }

    // 注销用户
    pub fn logout(user_id: &str) -> AppResult<()> {
        let mut tokens = TOKENS.lock().unwrap();
        tokens.remove(user_id);
        Ok(())
    }

    // 获取用户信息
    pub fn get_user_by_id(user_id: &str) -> AppResult<User> {
        let users = USERS.lock().unwrap();
        users
            .get(user_id)
            .cloned()
            .ok_or_else(|| AppError::NotFoundError("用户不存在".to_string()))
    }

    // 更新用户最后登录时间
    pub fn update_last_login_time(user_id: &str) -> AppResult<()> {
        let mut users = USERS.lock().unwrap();
        if let Some(user) = users.get_mut(user_id) {
            user.last_login_time = Some(chrono::Utc::now());
        }
        Ok(())
    }

    // 密码加密
    pub fn hash_password(password: &str) -> AppResult<String> {
        hash(password, DEFAULT_COST)
            .map_err(|e| AppError::SystemError(format!("密码加密失败: {}", e)))
    }

    // 密码验证
    pub fn verify_password(password: &str, hash: &str) -> AppResult<bool> {
        verify(password, hash)
            .map_err(|e| AppError::SystemError(format!("密码验证失败: {}", e)))
    }
}
